package abs.syn;

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.LinkedList;

public class SynTree {
	public SynTree  parent = null;
	public ArrayList<SynTree> children = null;

	public static SynTree buildFromString(String text){
		
		int start = 0, prev = 1;
		start = text.indexOf("(", prev);
		if (start == -1){
			start = text.length();
		}
		SynTree cur = new TagNode( text.substring(prev, start).trim()),
		root = cur;
		prev = start +1;
		while (prev < text.length()){

			start = text.indexOf("(", prev);
			if (start == -1){
				start = text.length();
			}
			if (cur.children==null)
				cur.children = new ArrayList<SynTree>();
			String str = text.substring(prev, start).trim();

			SynTree newNode = null;
			int wordEnd = str.indexOf(")") ;
			if (wordEnd== str.length() - 1){
				// XX)
				String[] pair = str.substring(0, str.length()-1).split(" ");
				newNode = new TagNode(pair[0]);
				addChild(cur, newNode);
				addChild(newNode,  new WordNode(pair[1]));
			}
			else{

				if (wordEnd==-1){
					// (XX (YY
					newNode = new TagNode(str);
					addChild(cur, newNode);
					cur = newNode;
				}else{
					// XX))))
					String[] pair = str.substring(0, wordEnd).split(" ");
					newNode = new TagNode(pair[0]);
					addChild(cur, newNode);
					addChild(newNode,  new WordNode(pair[1]));

					wordEnd ++;
					while (wordEnd < str.length() && str.charAt(wordEnd)==')'){
						if (cur.parent ==null&&cur!=root){
							System.err.println("missing parent for "+cur);
						}
						else
							cur = cur.parent;
						wordEnd++;
					}
				}
			}
			prev = start+1;
		}
		return root;
	}

	public void print(PrintStream out){
		// traverse a tree middle, left to right recursively
		if (isLeaf()){
			out.print(" "+getName()/*+")"*/);
		}
		else{
			out.print("("+getName()/*+" "*/);
			for (int i = 0; i < children.size(); i++)
				children.get(i).print(out);
			out.print(")");
		}
	}


	private static void addChild(SynTree parent, SynTree child){
		if(parent.children==null){
			parent.children = new ArrayList<SynTree>();
		}
		parent.children.add(child);
		if (child.parent==null)
			child.parent = parent;
		else{
			System.err.println("addChild@SynTree child already has a parent "+child);
		}
	}

	public boolean isLeaf(){
		return children == null || (children!=null && children.isEmpty());
	}
	public String getName(){return "SynTree";};
}
